package com.jyxd.web.service.czform;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.jyxd.web.controller.czform.vo.CRRTNurseCopyVo;
import com.jyxd.web.dao.basic.MonitorLifeDataDao;
import com.jyxd.web.dao.basic.NurseRecordFormDao;
import com.jyxd.web.dao.czform.CRRTAssessDao;
import com.jyxd.web.dao.czform.CRRTNurseDao;
import com.jyxd.web.data.basic.MonitorLifeData;
import com.jyxd.web.data.basic.NurseRecordForm;
import com.jyxd.web.data.czform.CRRTAssess;
import com.jyxd.web.data.czform.CRRTNurse;
import com.jyxd.web.data.dto.HttpResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.jyxd.web.util.DateUtil.*;
import static com.jyxd.web.util.ExecuteUtil.errorIfEmpty;
import static com.jyxd.web.util.UUIDUtil.getUUID;

@Service
public class CRRTNurseService {

    @Autowired
    private CRRTNurseDao crrtNurseDao;
    @Autowired
    private MonitorLifeDataDao monitorLifeDataDao;
    @Autowired
    private CRRTAssessDao crrtAssessDao;
    /*** 表单类型二 ***/
    public static final String CRRT_NURSE_TYPE_TWO = "two";
    /*** 表单类型三 ***/
    public static final String CRRT_NURSE_TYPE_THREE = "three";
    @Autowired
    private NurseRecordFormDao nurseRecordFormDao;

    /**
     * 新增或者修改
     *
     * @param crrtNurse
     * @return
     */
    public HttpResult saveOrUpdateCRRTNurse(CRRTNurse crrtNurse) {
        errorIfEmpty(crrtNurse, "表单内容不能为空");
        if (StringUtils.isEmpty(crrtNurse.getId())) {
            crrtNurse.setId(getUUID());
            crrtNurse.setStatus("1");
            crrtNurse.setCreateTime(new Date());
            crrtNurseDao.insert(crrtNurse);
            return new HttpResult(200, crrtNurse, "数据保存成功");
        }
        crrtNurseDao.update(crrtNurse);

        //更新顺延之后的数据 更新这几个字段"antiFreezing","anticoagulant","ultrafiltrationRate","bloodFlow","replacementRate","dialysisSpeed"
        crrtNurseDao.updateAfter(crrtNurse);
        return new HttpResult(200, crrtNurse, "数据修改成功");
    }

    /**
     * 查询数据列表
     *
     * @param map
     * @return
     */
    public HttpResult queryList(Map<String, Object> map) {
        errorIfEmpty(map, "表单内容不能为空");
        Integer totalCount = null;
        if (map.containsKey("start") && map.containsKey("size")) {
            totalCount = crrtNurseDao.queryNum(map);
            map.put("start", ((int) map.get("start") - 1) * (int) map.get("size"));
        }
        List<CRRTNurse> crrtNurseList = crrtNurseDao.queryList(map);
        if (CollectionUtils.isEmpty(crrtNurseList)) {
            return new HttpResult(200, "暂无数据");
        }
        return new HttpResult(200, crrtNurseList, totalCount, "查询数据成功");
    }

    /**
     * 根据条件查询数据
     *
     * @param map
     * @return
     */
    public List<CRRTNurse> getList(Map<String, Object> map) {
        return crrtNurseDao.queryList(map);
    }

    /**
     * 删除数据
     *
     * @param id
     * @return
     */
    public HttpResult deleteData(String id) {
        errorIfEmpty(id, "删除id不能为空");
        CRRTNurse crrtNurse = crrtNurseDao.queryData(id);
        errorIfEmpty(crrtNurse, "删除数据不存在");
        crrtNurse.setStatus("-1");
        crrtNurseDao.update(crrtNurse);
        return new HttpResult(200, "删除数据成功");
    }

    public HttpResult copyData(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数不存在");
        errorIfEmpty(map.get("patientId"), "查询患者id不存在");
        errorIfEmpty(map.get("crrtAssessId"), "CRRT前评估信息id不存在");
        CRRTNurseCopyVo crrtNurseCopyVo = buildCRRTNurseCopyVo((String)map.get("patientId"),(String)map.get("crrtAssessId"),(String) map.get("time"),null,0);
        return new HttpResult(200, crrtNurseCopyVo, "查询成功");
    }

    public List<CRRTNurse> batchGenerate(CRRTNurse origin, CRRTAssess crrtAssess) {
        List<CRRTNurse> list = new ArrayList<>();
        Date endTime = crrtAssess.getCloseTime();
        Date startTime = origin.getDataTime();
        if (startTime == null) {
            return list;
        }

        Date now = new Date();
        if (endTime == null || (endTime != null && endTime.compareTo(now) >= 0)) {
            endTime = now;
        }

        Calendar calendar = new GregorianCalendar();
        calendar.setTime(startTime);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        if (startTime.compareTo(calendar.getTime()) >= 0) {
            calendar.add(Calendar.HOUR_OF_DAY, 1);
        }
        startTime = calendar.getTime();

        calendar.setTime(endTime);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        endTime = calendar.getTime();

        while (startTime.compareTo(endTime) <= 0) {
            CRRTNurse crrtNurse = new CRRTNurse();
            crrtNurse.setId(getUUID());
            crrtNurse.setStatus("1");
            crrtNurse.setDataTime(startTime);
            crrtNurse.setCrrtAssessId(crrtAssess.getId());
            crrtNurse.setPatientId(crrtAssess.getPatientId());

            crrtNurse.setAntiFreezing(origin.getAntiFreezing());
            crrtNurse.setAnticoagulant(origin.getAnticoagulant());
            crrtNurse.setUltrafiltrationRate(origin.getUltrafiltrationRate());
            crrtNurse.setBloodFlow(origin.getBloodFlow());
            crrtNurse.setReplacementRate(origin.getReplacementRate());
            crrtNurse.setDialysisSpeed(origin.getDialysisSpeed());
            crrtNurse.setDataSource(1);

            CRRTNurseCopyVo crrtNurseCopyVo = buildCRRTNurseCopyVo(crrtAssess.getPatientId(), null, yyyyMMddHHmmssSdfToString(startTime), origin, 1);
            //赋值监护仪数据
            crrtNurse.setHr(crrtNurseCopyVo.getHr());
            crrtNurse.setResp(crrtNurseCopyVo.getResp());
            if(StringUtils.isNotEmpty(crrtNurseCopyVo.getNibps()) &&StringUtils.isNotEmpty(crrtNurseCopyVo.getNibpd())){
                crrtNurse.setBlood(crrtNurseCopyVo.getNibps() + "/" + crrtNurseCopyVo.getNibpd());
            }
            crrtNurse.setSpo2(crrtNurseCopyVo.getSpo2());
            list.add(crrtNurse);

            calendar.setTime(startTime);
            calendar.add(Calendar.HOUR_OF_DAY, 1);//把日期往后增加1小时
            startTime = calendar.getTime();
        }
        return list;
    }

    /**
     * 查询数据列表
     *
     * @param map
     * @return
     */
    public HttpResult queryListV2(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数不存在");
        errorIfEmpty(map.get("crrtAssessId"), "CRRT前评估信息id不存在");

        List<CRRTNurse> crrtNurseList = crrtNurseDao.queryList(map);
        if (CollectionUtils.isEmpty(crrtNurseList)) {
            return new HttpResult(200, "暂无数据");
        }

//        CRRTNurse crrtNurse = crrtNurseList.get(crrtNurseList.size() - 1);
//        CRRTAssess crrtAssess = crrtAssessDao.queryData(map.get("crrtAssessId").toString());
//        if (!Objects.isNull(crrtAssess) && !Objects.isNull(crrtNurse) && !Objects.isNull(crrtNurse.getDataTime())) {
//            List<CRRTNurse> list = batchGenerate(crrtNurse, crrtAssess);
//            if (!CollectionUtils.isEmpty(list)) {
//                crrtNurseDao.batchInsert(list);
//            }
//        }

        Integer totalCount = null;
        if (map.containsKey("start") && map.containsKey("size")) {
            totalCount = crrtNurseDao.queryNum(map);
            map.put("start", ((int) map.get("start") - 1) * (int) map.get("size"));
        }
        crrtNurseList = crrtNurseDao.queryList(map);
        if (CollectionUtils.isEmpty(crrtNurseList)) {
            return new HttpResult(200, "暂无数据");
        }

        if(crrtNurseList.size()==1){
            crrtNurseList.get(0).setUltrafiltrationQuantity(BigDecimal.ZERO.setScale(2).toPlainString());
            return new HttpResult(200, crrtNurseList, totalCount, "查询数据成功");
        }

        //合并自动生成数据
        List<CRRTNurse> resultList = new ArrayList<>();
        List<CRRTNurse> tempList = new ArrayList<>();
        Date dataTimeTemp = null;
        for (int i = 0; i < crrtNurseList.size(); i++) {
            CRRTNurse crrt = crrtNurseList.get(i);
            Date dataTime = crrt.getDataTime();

            if (dataTimeTemp == null) {
                tempList.add(crrt);
                dataTimeTemp = dataTime;
                continue;
            }

            if (dataTimeTemp.equals(dataTime)) {
                tempList.add(crrt);
                if (i + 1 == crrtNurseList.size()) {
                    dealTempList(tempList, resultList);
                    tempList = new ArrayList<>();
                }
                continue;
            }

            dealTempList(tempList, resultList);
            tempList = new ArrayList<>();
            tempList.add(crrt);
            dataTimeTemp = dataTime;
            if (i + 1 == crrtNurseList.size()) {
                dealTempList(tempList, resultList);
                break;
            }
        }

        //计算净超滤量  净超滤量   = sum（当条数据之前净超滤量） + ((当条数据时间-上调数据时间)[时间单位：小时]*上条数据超滤率)
        //每日8点重新计算，如果8点护士有手动录入，则后面累计（下一日8点重新开始累加），否则8点设置为0，之后累加
        CRRTNurse pre = null;
        BigDecimal totalUltrafiltrationQuantity = BigDecimal.ZERO;
        Date end = getEndDate(resultList.get(0).getDataTime());
        for (CRRTNurse crrt:resultList) {
            Date dataTime = crrt.getDataTime();
            if(Objects.isNull(pre)){
                if(StringUtils.isBlank(crrt.getUltrafiltrationQuantity())){
                    crrt.setUltrafiltrationQuantity(BigDecimal.ZERO.setScale(0).toPlainString());
                }
                totalUltrafiltrationQuantity = new BigDecimal(crrt.getUltrafiltrationQuantity());
            } else {
                if(dataTime.compareTo(end)>=0 && pre.getDataTime().compareTo(end)<0){
                    //重新赋值
                    if(StringUtils.isBlank(crrt.getUltrafiltrationQuantity())){
                        crrt.setUltrafiltrationQuantity(BigDecimal.ZERO.setScale(0).toPlainString());
                    }
                    totalUltrafiltrationQuantity = new BigDecimal(crrt.getUltrafiltrationQuantity());
                    end = getEndDate(dataTime);
                } else {
                    Date preDataTime = pre.getDataTime();
                    long intervalMilliseconds = dataTime.getTime() - preDataTime.getTime();
                    String ultrafiltrationRate = pre.getUltrafiltrationRate()==null?"0":pre.getUltrafiltrationRate();
                    BigDecimal ultrafiltrationQuantity = new BigDecimal(intervalMilliseconds + "").multiply(new BigDecimal(ultrafiltrationRate)).divide(new BigDecimal(1000 * 60 * 60 + ""), 0, RoundingMode.HALF_UP);
                    totalUltrafiltrationQuantity = totalUltrafiltrationQuantity.add(ultrafiltrationQuantity);
                    crrt.setUltrafiltrationQuantity(totalUltrafiltrationQuantity.setScale(0).toPlainString());
                }
            }
            pre = crrt;
        }
        return new HttpResult(200, resultList, totalCount, "查询数据成功");
    }

    private Date getEndDate(Date dataTime){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dataTime);

        calendar.set(Calendar.HOUR_OF_DAY, 8);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date temp = calendar.getTime();
        if(dataTime.compareTo(temp) >= 0){
            calendar.add(Calendar.DATE,1);
            return calendar.getTime();
        }
        return calendar.getTime();
    }

    private void dealTempList(List<CRRTNurse> tempList, List<CRRTNurse> resultList) {
        if (CollectionUtil.isEmpty(tempList)) {
            return;
        }
        if (tempList.size() == 1) {
            resultList.addAll(tempList);
            return;
        }

        //如果全部为人工添加数据，直接添加返回
        // 如果存在自动生成数据，则判断人工数据是否护理和监护仪字段为空，自动生成的数据赋值，remove自动生成数据
        List<CRRTNurse> manualList = tempList.stream().filter(crrt -> 0 == crrt.getDataSource()).collect(Collectors.toList());
        List<CRRTNurse> autoList = tempList.stream().filter(crrt -> 0 != crrt.getDataSource()).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(autoList)) {
            resultList.addAll(manualList);
            return;
        }

        CRRTNurse auto = autoList.get(0);
        if (CollectionUtil.isEmpty(manualList)) {
            resultList.add(auto);
        }

        for (CRRTNurse manual : manualList) {
            if (StringUtils.isBlank(manual.getAntiFreezing()))
                manual.setAntiFreezing(auto.getAntiFreezing());
            if (StringUtils.isBlank(manual.getAnticoagulant()))
                manual.setAnticoagulant(auto.getAnticoagulant());
            if (StringUtils.isBlank(manual.getUltrafiltrationRate()))
                manual.setUltrafiltrationRate(auto.getUltrafiltrationRate());
            if (StringUtils.isBlank(manual.getBloodFlow()))
                manual.setBloodFlow(auto.getBloodFlow());
            if (StringUtils.isBlank(manual.getReplacementRate()))
                manual.setReplacementRate(auto.getReplacementRate());
            if (StringUtils.isBlank(manual.getDialysisSpeed()))
                manual.setDialysisSpeed(auto.getDialysisSpeed());
            if (StringUtils.isBlank(manual.getHr()))
                manual.setHr(auto.getHr());
            if (StringUtils.isBlank(manual.getResp()))
                manual.setResp(auto.getResp());
            if (StringUtils.isBlank(manual.getBlood()))
                manual.setBlood(auto.getBlood());
            if (StringUtils.isBlank(manual.getSpo2()))
                manual.setSpo2(auto.getSpo2());
        }
        resultList.addAll(manualList);
    }

    private CRRTNurseCopyVo buildCRRTNurseCopyVo(String patientId,String crrtAssessId,String time,CRRTNurse crrtNurse,int datasource){
        CRRTNurseCopyVo crrtNurseCopyVo = new CRRTNurseCopyVo();
        //获取护理单数据
        Map<String,Object> map = new HashMap<>();
        map.put("patientId",patientId);
        map.put("dataTime",time);
        map.put("dataSource",0);
        NurseRecordForm nurseRecordForm = nurseRecordFormDao.queryByPatientAndDataTime(map);

        //获取监护仪数据
        MonitorLifeData queryMonitorLifeData = new MonitorLifeData();
        queryMonitorLifeData.setDateTime(time);
        queryMonitorLifeData.setPatientId(patientId);
        List<MonitorLifeData> monitorLifeDataList = monitorLifeDataDao.queryList(queryMonitorLifeData);
        if (CollectionUtils.isEmpty(monitorLifeDataList)) {
            queryMonitorLifeData.setDateTime(null);
            queryMonitorLifeData.setDateEndTime(time);
            Date date = null;
            try{
                date = yyyyMMddHHmmSdfToDate(time);
            } catch (Exception e){
            }
            Date startTime = getLaterMinuteDate(date, -30L);
            queryMonitorLifeData.setDateStartTime(yyyyMMddHHmmssSdfToString(startTime));
            monitorLifeDataList = monitorLifeDataDao.queryList(queryMonitorLifeData);
        }
        MonitorLifeData monitorLifeData = null;
        if(!CollectionUtils.isEmpty(monitorLifeDataList)){
            monitorLifeData = monitorLifeDataList.get(0);
        }

        if(Objects.nonNull(nurseRecordForm) && Objects.nonNull(monitorLifeData)){
            if(StringUtils.isNotEmpty(nurseRecordForm.getHr())){
                crrtNurseCopyVo.setHr(nurseRecordForm.getHr());
            } else {
                crrtNurseCopyVo.setHr(monitorLifeData.getHr());
            }

            if(StringUtils.isNotEmpty(nurseRecordForm.getBr())){
                crrtNurseCopyVo.setResp(nurseRecordForm.getBr());
            } else {
                crrtNurseCopyVo.setResp(monitorLifeData.getResp());
            }

            if(StringUtils.isNotEmpty(nurseRecordForm.getNbp())){
                String nbp = nurseRecordForm.getNbp();
                String[] split = nbp.split("/");
                if(split.length==2){
                    crrtNurseCopyVo.setNibps(split[0]);
                    crrtNurseCopyVo.setNibpd(split[1]);
                }
            } else {
                crrtNurseCopyVo.setNibps(monitorLifeData.getNibps());
                crrtNurseCopyVo.setNibpd(monitorLifeData.getNibpd());
            }

            if(StringUtils.isNotEmpty(nurseRecordForm.getSpO2())){
                crrtNurseCopyVo.setSpo2(nurseRecordForm.getSpO2());
            } else {
                crrtNurseCopyVo.setSpo2(monitorLifeData.getSpo2());
            }
        } else {
            if(Objects.nonNull(nurseRecordForm)){
                crrtNurseCopyVo.setHr(nurseRecordForm.getHr());
                crrtNurseCopyVo.setResp(nurseRecordForm.getBr());
                crrtNurseCopyVo.setSpo2(nurseRecordForm.getSpO2());
                if(StringUtils.isNotEmpty(nurseRecordForm.getNbp())){
                    String nbp = nurseRecordForm.getNbp();
                    String[] split = nbp.split("/");
                    if(split.length==2){
                        crrtNurseCopyVo.setNibps(split[0]);
                        crrtNurseCopyVo.setNibpd(split[1]);
                    }
                }
            }
            if(Objects.nonNull(monitorLifeData)){
                BeanUtil.copyProperties(monitorLifeData,crrtNurseCopyVo);
            }
        }
        
        //获取上一条crrt数据
        if(datasource == 0){
            map.put("crrtAssessId",crrtAssessId);
            List<CRRTNurse> crrtList = crrtNurseDao.queryList(map);
            if(!CollectionUtils.isEmpty(crrtList)) {
                crrtNurse = crrtList.get(crrtList.size() - 1);
            }
        }
        if(Objects.nonNull(crrtNurse)){
            crrtNurseCopyVo.setAntiFreezing(crrtNurse.getAntiFreezing());
            crrtNurseCopyVo.setAnticoagulant(crrtNurse.getAnticoagulant());
            crrtNurseCopyVo.setUltrafiltrationRate(crrtNurse.getUltrafiltrationRate());
            crrtNurseCopyVo.setBloodFlow(crrtNurse.getBloodFlow());
            crrtNurseCopyVo.setReplacementRate(crrtNurse.getReplacementRate());
            crrtNurseCopyVo.setDialysisSpeed(crrtNurse.getDialysisSpeed());
        }
        return crrtNurseCopyVo;
    }

    public void batchSync(Date date) {
        List<CRRTAssess> assessList = crrtAssessDao.getValidListByDate(date);
        List<CRRTNurse> list = new ArrayList<>();
        for (CRRTAssess crrtAssess:assessList) {
            CRRTNurse origin = crrtNurseDao.getLastByDateAndAssessId(date,crrtAssess.getId());
            CRRTNurse crrtNurse = new CRRTNurse();
            crrtNurse.setId(getUUID());
            crrtNurse.setStatus("1");
            crrtNurse.setDataTime(date);
            crrtNurse.setCrrtAssessId(crrtAssess.getId());
            crrtNurse.setPatientId(crrtAssess.getPatientId());
            if(Objects.isNull(origin)){
                crrtNurse.setAntiFreezing("0");
                crrtNurse.setAnticoagulant("0");
                crrtNurse.setUltrafiltrationRate("0");
                crrtNurse.setBloodFlow("0");
                crrtNurse.setReplacementRate("0");
                crrtNurse.setDialysisSpeed("0");
            } else {
                crrtNurse.setAntiFreezing(origin.getAntiFreezing());
                crrtNurse.setAnticoagulant(origin.getAnticoagulant());
                crrtNurse.setUltrafiltrationRate(origin.getUltrafiltrationRate());
                crrtNurse.setBloodFlow(origin.getBloodFlow());
                crrtNurse.setReplacementRate(origin.getReplacementRate());
                crrtNurse.setDialysisSpeed(origin.getDialysisSpeed());
            }
            crrtNurse.setDataSource(1);
            CRRTNurseCopyVo crrtNurseCopyVo = buildCRRTNurseCopyVo(crrtAssess.getPatientId(), null, yyyyMMddHHmmssSdfToString(date), origin, 1);
            //赋值监护仪数据
            crrtNurse.setHr(crrtNurseCopyVo.getHr());
            crrtNurse.setResp(crrtNurseCopyVo.getResp());
            if(StringUtils.isNotEmpty(crrtNurseCopyVo.getNibps()) &&StringUtils.isNotEmpty(crrtNurseCopyVo.getNibpd())){
                crrtNurse.setBlood(crrtNurseCopyVo.getNibps() + "/" + crrtNurseCopyVo.getNibpd());
            }
            crrtNurse.setSpo2(crrtNurseCopyVo.getSpo2());
            list.add(crrtNurse);
        }

        if (!CollectionUtils.isEmpty(list)) {
            crrtNurseDao.batchInsert(list);
        }
    }
}
